”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Golang 和 GoFr 更改运行时日志级别

使用 Golang 和 GoFr 更改运行时日志级别

发布于2024-07-30
浏览:820

在本文中,我将分享如何在不重新启动应用程序的情况下更改应用程序的日志级别。

介绍

日志级别通常被认为是按重要性排序:在开发中打开“不重要”级别(通知、调试等),但在开发中仅启用“最重要”级别(警告、错误等)。生产环境,CPU 时间和磁盘空间等资源非常宝贵。

但是,如果您的应用程序运行在 ERROR 级别并且您开始面临许多问题,但您无法从 ERROR 级别日志中找出答案,那么通过重新部署应用程序来更改日志级别将花费大量时间和资源。

此外,在生产中以 INFO 或 DEBUG 级别运行应用程序将生成大量日志,这些日志可能会压垮日志系统,导致 I/O 操作和资源消耗增加。

为了解决这些问题,GoFr - 终极 Golang 框架提供了一种安全的方法来更改日志级别,而无需重新启动应用程序。

更改日志级别

要更改日志级别,任何 GoFr 应用程序都需要以下配置:

REMOTE_LOG_URL= (e.g., https://log-service.com/log-levels?id=1)

GoFr 默认每 15 秒获取一次提供的端点以获取最新的日志级别,可以通过添加以下配置来增加或减少此间隔。

REMOTE_LOG_FETCH_INTERVAL= (default: 15)

日志级别服务

GoFr 要求 URL 的响应采用以下格式,并带有两个必填字段:

{
    "data": {
       "serviceName": "test-service",
       "logLevel": "DEBUG"
    }
}

让我们创建日志级别服务,它将为我们的应用程序提供日志级别。

我将使用 GoFr 创建服务,请参阅文档以了解更多信息。

我们将使用 MySQL 作为数据库,要添加 MySQL,请在 configs 目录中的 .env 文件中添加以下配置。

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=password
DB_NAME=log-level
DB_PORT=2001
DB_DIALECT=mysql

要运行 MySQL docker 容器,请运行以下命令

docker run --name gofr-logger -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=log-level -p 2001:3306 -d mysql:8.0.30

让我们添加带有迁移的 main.go 文件来创建表,我们将使用 AddRESTHandler 功能来注册路由。

main.go

package main

import (
 "gofr.dev/pkg/gofr"
 "gofr.dev/pkg/gofr/migration"
)

const createTable = `CREATE TABLE level (
    id INT PRIMARY KEY,
    service_name VARCHAR(255) NOT NULL,
    log_level VARCHAR(50) NOT NULL
);
`

func createTableLevel() migration.Migrate {
 return migration.Migrate{
  UP: func(d migration.Datasource) error {
   _, err := d.SQL.Exec(createTable)
   if err != nil {
    return err
   }

   return nil
  },
 }
}

type Level struct {
 ID          int    `json:"id"`
 ServiceName string `json:"serviceName"`
 LogLevel    string `json:"logLevel"`
}

func (u *Level) RestPath() string {
 return "level"
}

func main() {
 app := gofr.New()

 app.Migrate(map[int64]migration.Migrate{1: createTableLevel()})

 err := app.AddRESTHandlers(&Level{})
 if err != nil {
  app.Logger().Fatalf("Failed to register routes for level struct: %v", err)
 }

 app.Run()
}

运行日志服务后我们会看到如下日志:

LOGS FOR LOG-LEVEL CHANGE SERVICE STARTUP

我们已注册所有 REST 路线。

要创建服务,请发送以下请求:

curl --location 'localhost:8000/level' \
--header 'Content-Type: application/json' \
--data '{
    "id":1,
    "logLevel":"INFO",
    "serviceName":"gofr-app"
}'

要更新日志级别,请发送以下请求:

curl --location --request PUT 'localhost:8000/level/1' \
--header 'Content-Type: application/json' \
--data '{
    "id":1,
    "logLevel":"DEBUG",
    "serviceName":"gofr-app"
}'

要获取日志级别,请发送以下请求:

curl --location 'localhost:8000/level/1'

相同的 URL 将用于我们的应用程序的配置中,其日志级别必须远程更改。

结论

通过使用 GoFr 远程日志级别更改功能,您将获得以下好处:

  • 轻松调整:
    随时修改日志级别,无需重新启动应用程序。这在故障排除期间特别有用。

  • 增强可见性:
    轻松切换到更详细的日志级别(例如 DEBUG)以更深入地了解特定问题,然后切换回不太详细的级别(例如 INFO)以进行常规操作。

  • 改进的性能:
    生成大量日志会使日志系统不堪重负,导致 I/O 操作和资源消耗增加,更改为警告或错误级别可减少日志数量,增强性能,并降低云成本

通过给予 ⭐star 支持 GoFr: https://github.com/gofr-dev/gofr

此外,您可以访问免费公共端点来导出和查看应用程序的跟踪@tracer.gofr.dev。 
要启用它,请在您的 .env 文件中添加以下配置

TRACE_EXPORTER=gofr

其他福利:
如果您在开发或撰写文章方面为 GOFR 做出了贡献。您可以通过填写 GitHub 上的表格来获得免费的 赠品(T 恤、贴纸) 自述文件(位于底部)。

版本声明 本文转载于:https://dev.to/aryanmehrotra/remote-runtime-log-level-change-using-golang-gofr-54d8?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 查找当前执行JavaScript的脚本元素方法
    查找当前执行JavaScript的脚本元素方法
    如何引用当前执行脚本的脚本元素在某些方案中理解问题在某些方案中,开发人员可能需要将其他脚本动态加载其他脚本。但是,如果Head Element尚未完全渲染,则使用document.getElementsbytagname('head')[0] .appendChild(v)的常规方...
    编程 发布于2025-05-01
  • 如何在Chrome中居中选择框文本?
    如何在Chrome中居中选择框文本?
    选择框的文本对齐:局部chrome-inly-ly-ly-lyly solument 您可能希望将文本中心集中在选择框中,以获取优化的原因或提高可访问性。但是,在CSS中的选择元素中手动添加一个文本 - 对属性可能无法正常工作。初始尝试 state)</option> < op...
    编程 发布于2025-05-01
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-05-01
  • Python不会对超范围子串切片报错的原因
    Python不会对超范围子串切片报错的原因
    在python中用索引切片范围:二重性和空序列索引单个元素不同,该元素会引起错误,切片在序列的边界之外没有。这种行为源于索引和切片之间的基本差异。索引一个序列,例如“示例” [3],返回一个项目。但是,切片序列(例如“示例” [3:4])返回项目的子序列。索引不存在的元素时,例如“示例” [9] ...
    编程 发布于2025-05-01
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    编程 发布于2025-05-01
  • 版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    在时间戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源于遗留实现的关注,这些限制需要对当前的_timestamp功能进行特定的实现。 创建表`foo`( `Productid` int(10)unsigned not n...
    编程 发布于2025-05-01
  • 如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    编程 发布于2025-05-01
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-05-01
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 ; $ date->修改('1个月'); //前进1个月 echo $ date->...
    编程 发布于2025-05-01
  • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
    编程 发布于2025-05-01
  • 左连接为何在右表WHERE子句过滤时像内连接?
    左连接为何在右表WHERE子句过滤时像内连接?
    左JOIN CONUNDRUM:WITCHING小时在数据库Wizard的领域中变成内在的加入很有趣,当将c.foobar条件放置在上面的Where子句中时,据说左联接似乎会转换为内部连接。仅当满足A.Foo和C.Foobar标准时,才会返回结果。为什么要变形?关键在于其中的子句。当左联接的右侧值...
    编程 发布于2025-05-01
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-05-01
  • C++20 Consteval函数中模板参数能否依赖于函数参数?
    C++20 Consteval函数中模板参数能否依赖于函数参数?
    [ consteval函数和模板参数依赖于函数参数在C 17中,模板参数不能依赖一个函数参数,因为编译器仍然需要对非contexexpr futcoriations contim at contexpr function进行评估。 compile time。 C 20引入恒定函数,必须在编译时进行...
    编程 发布于2025-05-01
  • MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    在两个条件下插入或更新或更新 solution:的答案在于mysql的插入中...在重复键更新语法上。如果不存在匹配行或更新现有行,则此功能强大的功能可以通过插入新行来进行有效的数据操作。如果违反了唯一的密钥约束。实现所需的行为,该表必须具有唯一的键定义(在这种情况下为'名称'...
    编程 发布于2025-05-01
  • 表单刷新后如何防止重复提交?
    表单刷新后如何防止重复提交?
    在Web开发中预防重复提交 在表格提交后刷新页面时,遇到重复提交的问题是常见的。要解决这个问题,请考虑以下方法: 想象一下具有这样的代码段,看起来像这样的代码段:)){ //数据库操作... 回声“操作完成”; 死(); } ?> ...
    编程 发布于2025-05-01

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3